<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> 
    <title> - 天地维杰网</title>
    <meta name="keywords" content="系统架构,shutdown,不与天斗,Domino,博客,程序员,架构师,笔记,技术,分享,java,Redis">
    
    <meta property="og:title" content="">
    <meta property="og:site_name" content="天地维杰网">
    <meta property="og:image" content="/img/author.jpg"> 
    <meta name="title" content=" - 天地维杰网" />
    <meta name="description" content="天地维杰网 | 博客 | 软件 | 架构 | Java "> 
    <link rel="shortcut icon" href="http://www.shutdown.cn/img/favicon.ico" />
    <link rel="apple-touch-icon" href="http://www.shutdown.cn/img/apple-touch-icon.png" />
    <link rel="apple-touch-icon-precomposed" href="http://www.shutdown.cn/img/apple-touch-icon.png" />
    <link href="http://www.shutdown.cn/js/vendor/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />
    <link href="http://www.shutdown.cn/js/vendor/fancybox/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />
    <link href="http://www.shutdown.cn/css/main.css" rel="stylesheet" type="text/css" />
    <link href="http://www.shutdown.cn/css/syntax.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" id="hexo.configuration">
  var NexT = window.NexT || {};
  var CONFIG = {
    scheme: 'Pisces',
    sidebar: {"position":"left","display":"post"},
     fancybox: true, 
    motion: true
  };
</script>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7826003325059020" crossorigin="anonymous"></script>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div class="container one-collumn sidebar-position-left page-home  ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"> <div class="site-meta  custom-logo ">

  <div class="custom-logo-site-title">
    <a href="http://www.shutdown.cn"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">天地维杰网</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle">人如秋鸿来有信，事若春梦了无痕</p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
    <ul id="menu" class="menu">
      
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />首页
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/redis/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-battery-full"></i> <br />Redis
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/java/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-coffee"></i> <br />java
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/linux/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-linux"></i> <br />linux
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/daily/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-bug"></i> <br />日常问题
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/spring/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-child"></i> <br />Spring和Springboot
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/mac/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-fire"></i> <br />Mac相关
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/middleware/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-gavel"></i> <br />中间件
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/jiagou/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-rocket"></i> <br />架构
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/python/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-ship"></i> <br />python
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/front/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-bolt"></i> <br />前端
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/jvm/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-balance-scale"></i> <br />jvm
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/c/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-battery-empty"></i> <br />c语言
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/categories/web3/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-web3"></i> <br />web3
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/post/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />归档
          </a>
        </li>
      
        <li class="menu-item ">
          <a href="http://www.shutdown.cn/about/" rel="section">
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />关于
          </a>
        </li>
      
      <li class="menu-item menu-item-search">
        <a href="javascript:;" class="popup-trigger"> <i class="menu-item-icon fa fa-search fa-fw"></i> <br /> 搜索</a>
      </li>
    </ul>
    <div class="site-search">
      <div class="popup">
 <span class="search-icon fa fa-search"></span>
 <input type="text" id="local-search-input">
 <div id="local-search-result"></div>
 <span class="popup-btn-close">close</span>
</div>

    </div>
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            
<section id="posts" class="posts-expand">
  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
    <header class="post-header">
      <h1 class="post-title" itemprop="name headline">
        <a class="post-title-link" href="http://www.shutdown.cn/post/redis5.0%E4%BC%98%E5%8C%96-jemalloc5.1%E4%BA%8Cpurge%E6%94%B9%E8%BF%9B%E5%88%86%E6%9E%90/" itemprop="url">
        
        </a>
      </h1>
      <div class="post-meta">
      <span class="post-time">
<span class="post-meta-item-icon">
    <i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">时间：</span>
<time itemprop="dateCreated" datetime="2016-03-22T13:04:35+08:00" content="0001-01-01">
    0001-01-01
</time>
</span> 
      
      
       <span>
&nbsp; | &nbsp;
<span class="post-meta-item-icon">
    <i class="fa fa-eye"></i>
</span>
<span class="post-meta-item-text">阅读：</span>
<span class="leancloud-visitors-count">912 字 ~5分钟</span>
</span>
      </div>
    </header>
    <div class="post-body" itemprop="articleBody">
    

    

<blockquote>
<p>原文地址 <a href="https://youjiali1995.github.io/allocator/jemalloc-purge/">https://youjiali1995.github.io/allocator/jemalloc-purge/</a></p>
</blockquote>

<p><code>Redis</code> 之前一直使用 <code>4.0.3</code> 版本的 <code>jemalloc</code>，对 <code>dirty pages</code> 的回收比较暴力，相当于 <code>stop the world</code>。我们线上 <code>Redis</code> 偶尔也会出现 <code>RSS</code> 瞬间降低 <code>1GB</code> 并伴随大量报错的场景，之前看 <code>jemalloc</code> 源码也是为了解决这个问题。</p>

<p>最近(2018-05-24)，<code>Redis</code> 把 <code>jemalloc</code> 升级到了 <code>5.0.1</code> 版本，这次主要看一下对 <code>purge</code> 的改进。</p>

<h2 id="decay-based-purge">decay-based purge</h2>

<p><code>4.0.3</code> 是根据当前 <code>active_pages : dirty_pages</code> 的比例进行 <code>purge</code>，比如 <code>lg_dirty_mult:3</code>，当 <code>active_parges / dirty_pages &lt; 8</code> 时，就会把多余的 <code>purge</code> 掉，当比例在 <code>8</code> 波动时，就会频繁 <code>purge</code>，造成性能下降。</p>

<p><code>4.1.0</code> 新增了 <code>decay-based purge</code>，不再根据比例进行 <code>purge</code>，而是配置 <code>dirty page</code> 的存在时间，在这段时间内按照 <a href="https://en.wikipedia.org/wiki/Smoothstep">Smootherstep</a> 平滑的进行 <code>purge(1-&gt;0)</code>:</p>

<div  align="center"><img src="https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20220620155922.png" width = 500 /> </div>

<p>若使用 <code>decay-based purge</code>，<code>jemalloc</code> 在 <code>decay_time</code>(默认10s) 时间内分段(200次)进行 <code>dirty pages</code> 的回收，避免突发的大量 <code>dirty page</code> 回收影响性能。因为在 <code>purge</code> 的过程中， 会有新的 <code>dirty page</code> 产生，所以将整个 <code>purge</code> 划分为 <code>SMOOTHSTEP_NSTEPS(200)</code> 组，每组分别负责 <code>decay_interval(decay_time / SMOOTHSTEP_NSTEPS)</code> 时间内产生的 <code>dirty page</code> 的回收，每组能保留的 <code>dirty pages</code> 数量都是 <code>Smootherstep</code> 曲线，总的能保留的 <code>dirty page</code> 数量为 <code>200</code> 组的叠加，超出的会 <code>purge</code>。</p>

<h3 id="实现">实现</h3>

<p><code>arena</code> 中新增了如下字段：</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic"> * Approximate time in seconds from the creation of a set of unused
</span><span style="color:#8f5902;font-style:italic"> * dirty pages until an equivalent set of unused dirty pages is purged
</span><span style="color:#8f5902;font-style:italic"> * and/or reused.
</span><span style="color:#8f5902;font-style:italic"> */</span>
<span style="color:#000">ssize_t</span>			<span style="color:#000">decay_time</span><span style="color:#000;font-weight:bold">;</span>	<span style="color:#8f5902;font-style:italic">// 产生的 dirty pages 会在 decay_time 时间后全部 purge，默认为 10s。
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/* decay_time / SMOOTHSTEP_NSTEPS. */</span>
<span style="color:#000">nstime_t</span>		<span style="color:#000">decay_interval</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// decay 分为 SMOOTHSTEP_NSTEPS(200) 组，这是每组的时间间隔。
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic"> * Time at which the current decay interval logically started.  We do
</span><span style="color:#8f5902;font-style:italic"> * not actually advance to a new epoch until sometime after it starts
</span><span style="color:#8f5902;font-style:italic"> * because of scheduling and computation delays, and it is even possible
</span><span style="color:#8f5902;font-style:italic"> * to completely skip epochs.  In all cases, during epoch advancement we
</span><span style="color:#8f5902;font-style:italic"> * merge all relevant activity into the most recently recorded epoch.
</span><span style="color:#8f5902;font-style:italic"> */</span>
<span style="color:#000">nstime_t</span>		<span style="color:#000">decay_epoch</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 每组 decay 的起始时间
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/* decay_deadline randomness generator. */</span>
<span style="color:#000">uint64_t</span>		<span style="color:#000">decay_jitter_state</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 随机种子，用于计算下面的 decay_deadline
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic"> * Deadline for current epoch.  This is the sum of decay_interval and
</span><span style="color:#8f5902;font-style:italic"> * per epoch jitter which is a uniform random variable in
</span><span style="color:#8f5902;font-style:italic"> * [0..decay_interval).  Epochs always advance by precise multiples of
</span><span style="color:#8f5902;font-style:italic"> * decay_interval, but we randomize the deadline to reduce the
</span><span style="color:#8f5902;font-style:italic"> * likelihood of arenas purging in lockstep.
</span><span style="color:#8f5902;font-style:italic"> */</span>
<span style="color:#000">nstime_t</span>		<span style="color:#000">decay_deadline</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 每组 decay 的终止时间
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic"> * Number of dirty pages at beginning of current epoch.  During epoch
</span><span style="color:#8f5902;font-style:italic"> * advancement we use the delta between decay_ndirty and ndirty to
</span><span style="color:#8f5902;font-style:italic"> * determine how many dirty pages, if any, were generated, and record
</span><span style="color:#8f5902;font-style:italic"> * the result in decay_backlog.
</span><span style="color:#8f5902;font-style:italic"> */</span>
<span style="color:#000">size_t</span>			<span style="color:#000">decay_ndirty</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 每组 decay 开始时的 arena-&gt;ndirty(dirty page 数量)
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic"> * Memoized result of arena_decay_backlog_npages_limit() corresponding
</span><span style="color:#8f5902;font-style:italic"> * to the current contents of decay_backlog, i.e. the limit on how many
</span><span style="color:#8f5902;font-style:italic"> * pages are allowed to exist for the decay epochs.
</span><span style="color:#8f5902;font-style:italic"> */</span>
<span style="color:#000">size_t</span>			<span style="color:#000">decay_backlog_npages_limit</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 每次 purge 能够剩下的 dirty page 数量
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic"> * Trailing log of how many unused dirty pages were generated during
</span><span style="color:#8f5902;font-style:italic"> * each of the past SMOOTHSTEP_NSTEPS decay epochs, where the last
</span><span style="color:#8f5902;font-style:italic"> * element is the most recent epoch.  Corresponding epoch times are
</span><span style="color:#8f5902;font-style:italic"> * relative to decay_epoch.
</span><span style="color:#8f5902;font-style:italic"> */</span>
<span style="color:#000">size_t</span>			<span style="color:#000">decay_backlog</span><span style="color:#000;font-weight:bold">[</span><span style="color:#000">SMOOTHSTEP_NSTEPS</span><span style="color:#000;font-weight:bold">]</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 倒序(最后的为最新的 decay)保存了每组 decay 产生的 dirty page 数量，
</span><span style="color:#8f5902;font-style:italic"></span>                                                    <span style="color:#ce5c00;font-weight:bold">/</span><span style="color:#ce5c00;font-weight:bold">/</span> <span style="color:#a40000">根</span><span style="color:#a40000">据</span><span style="color:#a40000">这</span><span style="color:#a40000">个</span><span style="color:#a40000">计</span><span style="color:#a40000">算</span><span style="color:#a40000">能</span><span style="color:#a40000">够</span><span style="color:#a40000">保</span><span style="color:#a40000">存</span><span style="color:#a40000">的</span> <span style="color:#000">dirty</span> <span style="color:#000">page</span> <span style="color:#a40000">数</span><span style="color:#a40000">量</span><span style="color:#a40000">。</span></code></pre></div>
<p>新创建 <code>arena</code> 时，会调用 <code>arena_decay_init()</code> 设置 <code>decay</code> 初始状态：</p>

<ul>
<li><code>decay_time</code>：配置的值，产生的 <code>dirty pages</code> 会在 <code>decay_time</code> 时间后全部 <code>purge</code>，默认为 <code>10s</code>。</li>
<li><code>decay_interval</code>：<code>decay_time / SMOOTHSTEP_NSTEPS</code>，<code>decay</code> 分为 <code>SMOOTHSTEP_NSTEPS(200)</code> 组，这是每组的时间间隔。</li>
<li><code>decay_epoch</code>：每组 <code>decay</code> 的起始时间，设置为当前时间。</li>
<li><code>decay_jitter_state</code>：产生 <code>decay_deadline</code> 的随机种子，以 <code>arena</code> 地址为值。</li>
<li><code>decay_deadline</code>：随机产生在 <code>[decay_epoch + decay_interval, decay_epoch + 2*decay_interval)</code> 间。</li>
<li><code>decay_ndirty</code>: 设置为 <code>arena-&gt;ndirty</code>，每组 <code>decay</code> 开始时 <code>arena</code> 的 <code>dirty page</code> 个数。</li>
<li><code>decay_backlog_npages_limit</code>：这次 <code>purge</code> 之后能够保留的 <code>dirty page</code> 数量。</li>
<li><code>decay_backlog[SMOOTHSTEP_NSTEPS]</code>：初始化为0，保存每组 <code>decay</code> 产生的 <code>dirty page</code> 数量。</li>
</ul>

<p>因为按照时间进行 <code>purge</code>，所以需要时钟来触发 <code>decay purge</code>。<code>jemalloc</code> 使用内存分配和释放的次数作为时钟，当次数到达 <code>1000</code> 次时，尝试进行一次 <code>decay purge</code>:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#000">JEMALLOC_ALWAYS_INLINE</span> <span style="color:#204a87;font-weight:bold">void</span>
<span style="color:#000">arena_decay_ticks</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">tsd_t</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">tsd</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">arena_t</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">unsigned</span> <span style="color:#000">nticks</span><span style="color:#000;font-weight:bold">)</span>
<span style="color:#000;font-weight:bold">{</span>
	<span style="color:#000">ticker_t</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">decay_ticker</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">unlikely</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">tsd</span> <span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#204a87">NULL</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span>
		<span style="color:#204a87;font-weight:bold">return</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">decay_ticker</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">decay_ticker_get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">tsd</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">ind</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">unlikely</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">decay_ticker</span> <span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#204a87">NULL</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span>
		<span style="color:#204a87;font-weight:bold">return</span><span style="color:#000;font-weight:bold">;</span>
        <span style="color:#8f5902;font-style:italic">// 当 tick 为0时，才 purge，默认是1000次
</span><span style="color:#8f5902;font-style:italic"></span>	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">unlikely</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ticker_ticks</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">decay_ticker</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">nticks</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span>
		<span style="color:#000">arena_purge</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87">false</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
<span style="color:#000;font-weight:bold">}</span></code></pre></div>
<p>之后会调用 <code>arena_maybe_purge_decay()</code> 尝试 <code>decay purge</code>:</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#204a87;font-weight:bold">static</span> <span style="color:#204a87;font-weight:bold">void</span>
<span style="color:#000">arena_maybe_purge_decay</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena_t</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">)</span>
<span style="color:#000;font-weight:bold">{</span>
	<span style="color:#000">nstime_t</span> <span style="color:#000">time</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">size_t</span> <span style="color:#000">ndirty_limit</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#000">assert</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">opt_purge</span> <span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">purge_mode_decay</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#8f5902;font-style:italic">/* Purge all or nothing if the option is disabled. */</span>
	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_time</span> <span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span>
		<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_time</span> <span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">)</span>
			<span style="color:#000">arena_purge_to_limit</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
		<span style="color:#204a87;font-weight:bold">return</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000;font-weight:bold">}</span>

	<span style="color:#000">nstime_copy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">time</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_epoch</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">unlikely</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">nstime_update</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">time</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#8f5902;font-style:italic">// 设置 time 为当前时间
</span><span style="color:#8f5902;font-style:italic"></span>		<span style="color:#8f5902;font-style:italic">/* Time went backwards.  Force an epoch advance. */</span>
		<span style="color:#000">nstime_copy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">time</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_deadline</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 当时间回退时，设置时间为 deadline
</span><span style="color:#8f5902;font-style:italic"></span>	<span style="color:#000;font-weight:bold">}</span>

	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena_decay_deadline_reached</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">time</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#8f5902;font-style:italic">// arena-&gt;decay_deadline &lt;= time 到达 deadline
</span><span style="color:#8f5902;font-style:italic"></span>		<span style="color:#000">arena_decay_epoch_advance</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">time</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>  <span style="color:#8f5902;font-style:italic">// 更新 epoch 和 统计
</span><span style="color:#8f5902;font-style:italic"></span>
	<span style="color:#000">ndirty_limit</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">arena_decay_npages_limit</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 计算这次 purge 能够剩下的 dirty page 数量
</span><span style="color:#8f5902;font-style:italic"></span>
	<span style="color:#8f5902;font-style:italic">/*
</span><span style="color:#8f5902;font-style:italic">	 * Don&#39;t try to purge unless the number of purgeable pages exceeds the
</span><span style="color:#8f5902;font-style:italic">	 * current limit.
</span><span style="color:#8f5902;font-style:italic">	 */</span>
	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">ndirty</span> <span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">ndirty_limit</span><span style="color:#000;font-weight:bold">)</span>
		<span style="color:#204a87;font-weight:bold">return</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">arena_purge_to_limit</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">ndirty_limit</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 进行 purge，purge 之后剩下的数量为 ndirty_limit
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#000;font-weight:bold">}</span></code></pre></div>
<p>最关键的为 <code>arena_decay_epoch_advance()</code>：</p>
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#204a87;font-weight:bold">static</span> <span style="color:#204a87;font-weight:bold">void</span>
<span style="color:#000">arena_decay_epoch_advance</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena_t</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">nstime_t</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">time</span><span style="color:#000;font-weight:bold">)</span>
<span style="color:#000;font-weight:bold">{</span>
	<span style="color:#000">uint64_t</span> <span style="color:#000">nadvance</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">nstime_t</span> <span style="color:#000">delta</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">size_t</span> <span style="color:#000">ndirty_delta</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#000">assert</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">opt_purge</span> <span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">purge_mode_decay</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">assert</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena_decay_deadline_reached</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">time</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#000">nstime_copy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">delta</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">time</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">nstime_subtract</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">delta</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_epoch</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">nadvance</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">nstime_divide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">delta</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_interval</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 计算过去了多少 interval
</span><span style="color:#8f5902;font-style:italic"></span>	<span style="color:#000">assert</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">nadvance</span> <span style="color:#ce5c00;font-weight:bold">&gt;</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#8f5902;font-style:italic">/* Add nadvance decay intervals to epoch. */</span>
	<span style="color:#000">nstime_copy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">delta</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_interval</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">nstime_imultiply</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">delta</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">nadvance</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">nstime_add</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_epoch</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">delta</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 设置 decay_epoch 为这次 decay 的起始时间
</span><span style="color:#8f5902;font-style:italic"></span>
	<span style="color:#8f5902;font-style:italic">/* Set a new deadline. */</span>
	<span style="color:#000">arena_decay_deadline_init</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>

	<span style="color:#8f5902;font-style:italic">/* Update the backlog. */</span>
        <span style="color:#8f5902;font-style:italic">/* arena-&gt;decay_backlog[] 保存了每组 decay 产生的 dirty page 数量，最后的为最新的(因为 smootherstep 是从0~1)
</span><span style="color:#8f5902;font-style:italic">         * 当过去 interval 时，decay_backlog[] 中的数据会左移，相当于时间窗口移动
</span><span style="color:#8f5902;font-style:italic">         */</span>
	<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">nadvance</span> <span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">SMOOTHSTEP_NSTEPS</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span>
		<span style="color:#000">memset</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_backlog</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">SMOOTHSTEP_NSTEPS</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#ce5c00;font-weight:bold">*</span>
		    <span style="color:#204a87;font-weight:bold">sizeof</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">size_t</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000;font-weight:bold">}</span> <span style="color:#204a87;font-weight:bold">else</span> <span style="color:#000;font-weight:bold">{</span>
		<span style="color:#000">memmove</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_backlog</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_backlog</span><span style="color:#000;font-weight:bold">[</span><span style="color:#000">nadvance</span><span style="color:#000;font-weight:bold">]</span><span style="color:#000;font-weight:bold">,</span>
		    <span style="color:#000;font-weight:bold">(</span><span style="color:#000">SMOOTHSTEP_NSTEPS</span> <span style="color:#ce5c00;font-weight:bold">-</span> <span style="color:#000">nadvance</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#204a87;font-weight:bold">sizeof</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">size_t</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
		<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">nadvance</span> <span style="color:#ce5c00;font-weight:bold">&gt;</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span>
			<span style="color:#000">memset</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_backlog</span><span style="color:#000;font-weight:bold">[</span><span style="color:#000">SMOOTHSTEP_NSTEPS</span> <span style="color:#ce5c00;font-weight:bold">-</span>
			    <span style="color:#000">nadvance</span><span style="color:#000;font-weight:bold">]</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">nadvance</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#204a87;font-weight:bold">sizeof</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">size_t</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span>
		<span style="color:#000;font-weight:bold">}</span>
	<span style="color:#000;font-weight:bold">}</span>
        <span style="color:#8f5902;font-style:italic">// 这次 decay 时间间隔内产生的 dirty page 数量
</span><span style="color:#8f5902;font-style:italic"></span>	<span style="color:#000">ndirty_delta</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">ndirty</span> <span style="color:#ce5c00;font-weight:bold">&gt;</span> <span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_ndirty</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#ce5c00;font-weight:bold">?</span> <span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">ndirty</span> <span style="color:#ce5c00;font-weight:bold">-</span>
	    <span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f57900">decay_ndirty</span> <span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span>
	<span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_ndirty</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">ndirty</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 保留当前的 dirty page 数量，为了下一次计算 ndirty_delta
</span><span style="color:#8f5902;font-style:italic"></span>	<span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_backlog</span><span style="color:#000;font-weight:bold">[</span><span style="color:#000">SMOOTHSTEP_NSTEPS</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">]</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">ndirty_delta</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 保存这次 decay 产生的 dirty page 数量
</span><span style="color:#8f5902;font-style:italic"></span>	<span style="color:#000">arena</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000">decay_backlog_npages_limit</span> <span style="color:#ce5c00;font-weight:bold">=</span>
	    <span style="color:#000">arena_decay_backlog_npages_limit</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">arena</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#8f5902;font-style:italic">// 根据 smootherstep 计算这次 decay 之后能够剩下的 dirty page 数量
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#000;font-weight:bold">}</span></code></pre></div>
<h2 id="tow-phase-decay-purge">tow-phase decay purge</h2>

<p><code>jemalloc 4.0.3</code> 版本在 <code>Linux</code> 系统下是调用 <code>madvise(..., MADV_DONTNEED)</code> 来回收内存，这是强制的、立即生效的(<code>RSS</code> 立即释放)，所以 <code>overhead</code> 会比较大。</p>

<p><code>Linux 4.5</code> 之后支持 <code>MADV_FREE</code>，内存不再立即回收，当操作系统有内存压力后才会回收，<code>overhead</code> 很小。<code>jemalloc 5.0.0</code> 实现了 <code>two-phase purge</code>：</p>

<ul>
<li><code>page</code> 分为 <code>3</code> 种状态：<code>dirty -&gt; muzzy -&gt; clean</code></li>
<li><code>purge</code>分为<code>2</code>个阶段：

<ul>
<li><code>dirty -&gt; muzzy</code>: 调用 <code>madvise(..., MADV_FREE)</code> 由操作系统释放</li>
<li><code>muzzy -&gt; clean</code>: 调用 <code>madvise(..., MADV_DONTNEED)</code> 强制释放</li>
</ul></li>
<li><code>2</code> 个阶段均使用 <code>decay-based purge</code>，分别设置配置。可以设置 <code>lazy-purging</code> 的时间短(快速回收)，<code>fored-purging</code> 的时间长(慢速回收)。</li>
</ul>

<h2 id="background-thread">background thread</h2>

<p><code>jemalloc 5.0.0</code> 实现了 <code>asynchronous decay-driven unused dirty page purging</code>，开启之后，最多创建 <code>CPU</code> 个数的线程，并设置 <code>CPU</code> 亲和力，<code>decay-based purging</code> 会由 <code>background thread</code> 来执行， 不影响正常的工作。</p>

<h2 id="结论">结论</h2>

<p>高版本 <code>jemalloc</code> 对 <code>purge</code> 进行了很多优化，能够减少内存回收的影响。</p>

    </div>
    <footer class="post-footer">
     

     <div class="post-nav">
    <div class="post-nav-next post-nav-item">
    
        <a href="http://www.shutdown.cn/post/redis5.0%E4%BC%98%E5%8C%96-jemalloc5.1%E4%B8%80%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90/" rel="next" title="">
        <i class="fa fa-chevron-left"></i> 
        </a>
    
    </div>

    <div class="post-nav-prev post-nav-item">
    
        <a href="http://www.shutdown.cn/post/redis5.0%E4%BC%98%E5%8C%96-%E5%85%B6%E4%BB%96/" rel="prev" title="">
         <i class="fa fa-chevron-right"></i>
        </a>
    
    </div>
</div>
      
     
     
     






    </footer>
  </article>
</section>

          </div>
        </div>
        <div class="sidebar-toggle">
  <div class="sidebar-toggle-line-wrap">
    <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
    <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
    <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
  </div>
</div>
<aside id="sidebar" class="sidebar">
  <div class="sidebar-inner">

    <section class="site-overview sidebar-panel  sidebar-panel-active ">
      <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image"
        src="http://www.shutdown.cn/img/author.jpg"
        alt="不与天斗Domino" />
    <p class="site-author-name" itemprop="name">不与天斗Domino</p>
    <p class="site-description motion-element" itemprop="description"> 
        Programmer &amp; Architect</p>
</div>
      <nav class="site-state motion-element">
    <div class="site-state-item site-state-posts">
      <a href="http://www.shutdown.cn/post/">
        <span class="site-state-item-count">183</span>
        <span class="site-state-item-name">日志</span>
      </a>
    </div>
    <div class="site-state-item site-state-categories">    
        <a href="http://www.shutdown.cn/categories/">      
         
        <span class="site-state-item-count">15</span>
        
        <span class="site-state-item-name">分类</span>
        
        </a>
    </div>

    <div class="site-state-item site-state-tags">
        <a href="http://www.shutdown.cn/tags/">
         
        <span class="site-state-item-count">224</span>
        
        <span class="site-state-item-name">标签</span>
        </a>
    </div>
</nav>
      
      

      

      <div class="links-of-blogroll motion-element inline">
<script type="text/javascript" src="//rf.revolvermaps.com/0/0/8.js?i=&amp;m=0&amp;s=220&amp;c=ff0000&amp;cr1=ffffff&amp;f=arial&amp;l=33&amp;bv=35" async="async"></script>
</div>

    </section>
    
  </div>
</aside>

      </div>
    </main>
   
    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  <span itemprop="copyrightYear">  &copy; 
  2013 - 2023</span>
  <span class="with-love"><i class="fa fa-heart"></i></span>
  <span class="author" itemprop="copyrightHolder">天地维杰网</span>
  <span class="icp" itemprop="copyrightHolder"><a href="https://beian.miit.gov.cn/" target="_blank">京ICP备13019191号-1</a></span>
</div>
<div class="powered-by">
  Powered by - <a class="theme-link" href="http://gohugo.io" target="_blank" title="hugo" >Hugo v0.63.2</a>
</div>
<div class="theme-info">
  Theme by - <a class="theme-link" href="https://github.com/xtfly/hugo-theme-next" target="_blank"> NexT
  </a>
</div>


      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
      <span id="scrollpercent"><span>0</span>%</span>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>
<script type="text/javascript" src="http://www.shutdown.cn/js/vendor/jquery/index.js?v=2.1.3"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/vendor/fastclick/lib/fastclick.min.js?v=1.0.6"></script> 
<script type="text/javascript" src="http://www.shutdown.cn/js/vendor/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/vendor/velocity/velocity.min.js?v=1.2.1"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/vendor/velocity/velocity.ui.min.js?v=1.2.1"></script>
<script src="http://www.shutdown.cn/js/vendor/ua-parser-js/dist/ua-parser.min.js?v=0.7.9"></script>

<script src="http://www.shutdown.cn/js/vendor/fancybox/jquery.fancybox.pack.js?v=2.1.5"></script>

<script type="text/javascript" src="http://www.shutdown.cn/js/utils.js"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/motion.js"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/affix.js"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/schemes/pisces.js"></script>

<script type="text/javascript" src="http://www.shutdown.cn/js/scrollspy.js"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/post-details.js"></script>
<script type="text/javascript" src="http://www.shutdown.cn/js/toc.js"></script>

<script type="text/javascript" src="http://www.shutdown.cn/js/bootstrap.js"></script>

<script type="text/javascript" src="http://www.shutdown.cn/js/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX", "output/HTML-CSS"],
    tex2jax: {
      inlineMath: [ ['$','$'] ],
      displayMath: [ ['$$','$$'] ],
      processEscapes: true
    },
    "HTML-CSS": { fonts: ["TeX"] }
  });
</script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML' async></script>
</body>
</html>